package br.usp.ime.amazon;

import java.io.IOException;
import java.util.ArrayList;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.http.json.JsonHttpRequest;
import com.google.api.client.http.json.JsonHttpRequestInitializer;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.books.Books;
import com.google.api.services.books.BooksRequest;
import com.google.api.services.books.Books.Volumes.List;
import com.google.api.services.books.model.Volume;
import com.google.api.services.books.model.VolumeVolumeInfo;
import com.google.api.services.books.model.Volumes;

public class SearchGoogleBooks extends HttpServlet {

	private static final long serialVersionUID = 1L;
	public static final String AccessKeyId = "AKIAIHI5I2MDY5OUEFKQ";
	public static final String SecretId = "4t4E2ubVlAd682rCSWDa9BwqO+q80HO++cw977Om";
	public static final String AssociateTag = "httppessoalut-20";
	public static final long MAX_SEARCH = 40;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		cleanSession(req);
		resp.sendRedirect("indexGoogleBooks.jsp");
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		cleanSession(req);

		ResultSearch r = new ResultSearch();

		String query = generateQuery(req);

		final Books books = initGoogleBooksService();

		List volumesList = books.volumes().list(query);
		volumesList.setMaxResults(MAX_SEARCH);

		int page = 0;
		boolean hasMoreItems = doSearch(r, page, volumesList);

		while (hasMoreItems) {
			hasMoreItems = doSearch(r, page++, volumesList);
		}

		r.setTotal(r.getBooks().size());

		if (r.getTotal() > 0) {
			req.getSession().setAttribute("result", r);
		}
		req.getSession().setAttribute("query", query);
		resp.sendRedirect("results.jsp");

	}

	private void cleanSession(HttpServletRequest req) {
		req.getSession().removeAttribute("result");
		req.getSession().removeAttribute("search");
	}

	private boolean doSearch(ResultSearch r, int page, List volumesList)
			throws IOException {
		Volumes volumes = null;
		volumesList.setStartIndex((long) page * MAX_SEARCH);
		try {
			volumes = volumesList.execute();
		} catch (GoogleJsonResponseException e) {
			// message already includes parsed response
			System.err.println(e.getMessage());
		} catch (HttpResponseException e) {
			// message doesn't include parsed response
			System.err.println(e.getMessage());
			System.err.println(e.getResponse().parseAsString());
		}
		return populateBook(volumes, r);
	}

	private Books initGoogleBooksService() {
		JsonFactory jsonFactory = new JacksonFactory();
		Books books = null;
		try {
			books = Books
					.builder(new NetHttpTransport(), jsonFactory)
					.setApplicationName("Google-BooksSample/1.0")
					.setJsonHttpRequestInitializer(
							new JsonHttpRequestInitializer() {
								@Override
								public void initialize(JsonHttpRequest request) {
									BooksRequest booksRequest = (BooksRequest) request;
									booksRequest
											.setKey("AIzaSyAJDvhMhPWMH6wnfW2AYDPUp4urYC-DEvc");
								}
							}).build();

		} catch (Throwable t) {
			t.printStackTrace();
		}
		return books;
	}

	private boolean populateBook(Volumes volumes, ResultSearch r) {

		if (volumes==null || volumes.getItems() == null) {
			return false;
		}
		for (Volume volume : volumes.getItems()) {
			Book b = new Book();
			VolumeVolumeInfo volumeInfo = volume.getVolumeInfo();
			b.setTitle(volumeInfo.getTitle());
			if(volumeInfo.getAuthors()!=null)
				b.setAuthors(volumeInfo.getAuthors());
			if (volumeInfo.getIndustryIdentifiers() != null) {
				b.setASIN(volumeInfo.getIndustryIdentifiers().get(0)
						.getIdentifier());
				b.setIsbn(volumeInfo.getIndustryIdentifiers().get(0)
						.getIdentifier());
			}
			b.setDetailPageURL(volumeInfo.getInfoLink());
			b.setEdition("");
			b.setManufacture(volumeInfo.getPublisher());
			b.setPublication(volumeInfo.getPublishedDate());
			if (volumeInfo.getImageLinks() != null) {
				b.setUrlLargeImage(volumeInfo.getImageLinks().getThumbnail());
				b.setUrlMediumImage(volumeInfo.getImageLinks()
						.getSmallThumbnail());
			}
			r.getBooks().add(b);
		}
		return (volumes.getItems().size() == MAX_SEARCH);
	}

	private String generateQuery(HttpServletRequest req) {
		java.util.List<String> list = new ArrayList<String>();

		String keywords = req.getParameter("keywords");
		String[] authors = req.getParameterValues("inauthor");
		String title = req.getParameter("intitle");
		String isbn = req.getParameter("isbn");
		String publisher = req.getParameter("inpublisher");
		String subject = req.getParameter("subject");

		if (keywords.trim().length() > 0) {
			list.add(keywords.trim());
		}

		for (int i = 0; i < authors.length; i++) {
			if (authors[i].trim().length() > 0) {
				list.add("inauthor:" + authors[i].trim());
			}
		}

		if (title.trim().length() > 0) {
			list.add("intitle:" + title.trim());
		}
		if (isbn.trim().length() > 0) {
			list.add("isbn:" + isbn.trim());
		}
		if (publisher.trim().length() > 0) {
			list.add("inpublisher:" + publisher.trim());
		}
		if (subject.length() > 0) {
			list.add("subject:" + subject.trim());
		}

		if (list.isEmpty()) {
			return null;
		}
		String search = "";
		if (!list.isEmpty()) {
			search = list.get(0);
			for (int i = 1; i < list.size(); i++) {
				search += "+" + list.get(i);
			}
		}
		return search;
	}
}